package com.kz.framework.helper;

import com.kz.framework.annotation.MyRequestMapping;
import com.kz.framework.entity.Handler;
import com.kz.framework.entity.Request;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @description: 控制器助手类 相当于SpringMVC里的映射处理器, 为请求URI设置对应的处理器
 * @author zhgp
 * @date 2021/6/21 20:46
 * @version 1.0
 */
public final class ControllerHelper {

    /**
     * REQUEST_MAP为 "请求-处理器(请求类型【requestMethod-url】-controller方法)" 的映射
     */
    private static final Map<Request, Handler> REQUEST_MAP = new HashMap();

    static {
        // 遍历所有Controller类
        Set<Class<?>> controllerClassSet = ClassHelper.getControllerClassSet();
        if (CollectionUtils.isNotEmpty(controllerClassSet)) {
            for (Class<?> controllerClass : controllerClassSet) {
                // 暴力反射获取所有方法
                Method[] methods = controllerClass.getDeclaredMethods();
                // 遍历方法
                if (ArrayUtils.isEmpty(methods)) {
                    continue;
                }
                for (Method method : methods) {
                    // 判断是否带RequestMapping注解
                    if (!method.isAnnotationPresent(MyRequestMapping.class)) {
                        continue;
                    }
                    MyRequestMapping requestMapping = method.getAnnotation(MyRequestMapping.class);
                    // 请求路径，注解中的value值
                    String requestPath = requestMapping.value();
                    // 请求方法
                    String requestMethod = requestMapping.method().name();

                    // 封装请求和处理器
                    Request request = new Request(requestMethod, requestPath);
                    Handler handler = new Handler(controllerClass, method);
                    if (REQUEST_MAP.containsKey(request)) {
                        throw new RuntimeException("MyRequestMapping value and requestMethod duplicate, Please check.");
                    }
                    REQUEST_MAP.put(request, handler);
                }

            }
        }
    }

    /**
     * 获取 Handler
     */
    public static Handler getHandler(Request request) {
        return REQUEST_MAP.get(request);
    }
}
